package com.hardydou.framework.quartz;

import cn.hutool.core.date.DateUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

/**
 * @author ：hardy
 * @description：
 * @date ：Created in 2020/6/24
 * @Copyright ：Hardydou.com
 */
@Service
public class QuartzService {
    private Log log = LogFactory.get(QuartzService.class);

    @Autowired
    private Scheduler scheduler;

    public void clear() {
        try {
            scheduler.clear();
        } catch (Exception e) {
            log.error(e);
        }
    }

    /**
     * 提交任务
     */
    public void addTask(QuartzTask quartzTask) {
        try {
            String taskName = quartzTask.getTaskName(),
                    taskGroup = quartzTask.getTaskGroup(),
                    cronExpression = quartzTask.getCronExpression(),
                    remark = quartzTask.getRemark();
            String invokeParams = quartzTask.getInvokeParam();
            if (checkExists(quartzTask)) {
                //error
            }
            TriggerKey triggerKey = TriggerKey.triggerKey(taskName, taskGroup);
            JobKey jobKey = JobKey.jobKey(taskName, taskGroup);

            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).
                    withDescription(remark).withSchedule(scheduleBuilder).build();

            trigger.getJobDataMap().put("invokeParam", invokeParams);

            Class<? extends Job> clazz = (Class<? extends Job>) Class.forName(quartzTask.getTaskClass());
            JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(jobKey).withDescription(remark).build();
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException | ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    public void resumeTask(QuartzTask quartzTask) {
        try {
            scheduler.resumeJob(JobKey.jobKey(quartzTask.getTaskName(), quartzTask.getTaskGroup()));
        } catch (Exception e) {
            log.error("", e);
        }
    }

    public void updateTask(QuartzTask info) {
        String taskName = info.getTaskName(),
                taskGroup = info.getTaskGroup(),
                cronExpression = info.getCronExpression(),
                remark = info.getRemark(),
                createTime = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        String invokeParams = info.getInvokeParam();
        try {
            if (!checkExists(info)) {
                //Error
            }
            TriggerKey triggerKey = TriggerKey.triggerKey(taskName, taskGroup);
            JobKey jobKey = new JobKey(taskName, taskGroup);
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
            CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withDescription(createTime).withSchedule(cronScheduleBuilder).build();
            cronTrigger.getJobDataMap().put("invokeParam", invokeParams);
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            jobDetail.getJobBuilder().withDescription(remark);
            Set<Trigger> triggerSet = new HashSet<>();
            triggerSet.add(cronTrigger);
            scheduler.scheduleJob(jobDetail, triggerSet, true);
        } catch (SchedulerException e) {
            log.error("", e);
        }
    }

    public void pauseTask(QuartzTask quartzTask) {
        TriggerKey triggerKey = TriggerKey.triggerKey(quartzTask.getTaskName(), quartzTask.getTaskGroup());
        try {
            if (checkExists(quartzTask)) {
                scheduler.pauseTrigger(triggerKey);
            }
        } catch (Exception e) {
            log.error("", e);
        }
    }

    public void deleteTask(QuartzTask quartzTask) {
        TriggerKey triggerKey = TriggerKey.triggerKey(quartzTask.getTaskName(), quartzTask.getTaskGroup());
        try {
            if (checkExists(quartzTask)) {
                scheduler.pauseTrigger(triggerKey);
                scheduler.unscheduleJob(triggerKey);
            }
        } catch (SchedulerException e) {
            log.error("", e);
        }
    }

    private boolean checkExists(QuartzTask task) throws SchedulerException {
        return scheduler.checkExists(getTriggerKey(task));
    }

    private TriggerKey getTriggerKey(QuartzTask task) {
        return TriggerKey.triggerKey(task.getTaskName(), task.getTaskGroup());
    }


}
